//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package roadmap_user_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/roadmap_dao"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/roadmap_user_api"
	"go.mongodb.org/mongo-driver/mongo"
)

func (apiImpl *RoadmapUserApiImpl) SetAccess(ctx context.Context, req *roadmap_user_api.SetAccessRequest) (*roadmap_user_api.SetAccessResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_user_api.SetAccessResponse{
			Code:   roadmap_user_api.SetAccessResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	exist, err := roadmap_dao.RoadmapInfoDao.Exist(ctx, req.RoadmapId, false, false)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_user_api.SetAccessResponse{
			Code:   roadmap_user_api.SetAccessResponse_CODE_NO_ROADMAP,
			ErrMsg: "路线图不存在",
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = roadmap_dao.AccessRecordDao.Upsert(sessCtx, &roadmap_dao.AccessRecordDbItem{
			RoadmapId:          req.RoadmapId,
			UserId:             sessionItem.UserId,
			TimeStamp:          nowTime,
			DoneTopicCount:     req.DoneTopicCount,
			TotalTopicCount:    req.TotalTopicCount,
			DoneSubTopicCount:  req.DoneSubTopicCount,
			TotalSubTopicCount: req.TotalSubTopicCount,
		})
		if err != nil {
			return nil, err
		}
		//增加热度值
		err = roadmap_dao.RoadmapInfoDao.IncHotValue(sessCtx, req.RoadmapId, 1)
		if err != nil {
			return nil, err
		}
		return &roadmap_user_api.SetAccessResponse{
			Code: roadmap_user_api.SetAccessResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_user_api.SetAccessResponse), nil
}

func (apiImpl *RoadmapUserApiImpl) ListAccess(ctx context.Context, req *roadmap_user_api.ListAccessRequest) (*roadmap_user_api.ListAccessResponse, error) {
	emptyList := []*roadmap_user_api.AccessRecord{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_user_api.ListAccessResponse{
			Code:       roadmap_user_api.ListAccessResponse_CODE_WRONG_SESSION,
			ErrMsg:     "会话不存在",
			RecordList: emptyList,
		}, nil
	}

	count, err := roadmap_dao.AccessRecordDao.CountByUser(ctx, sessionItem.UserId)
	if err != nil {
		return nil, err
	}
	accessItemList, err := roadmap_dao.AccessRecordDao.ListByUser(ctx, sessionItem.UserId, int64(req.Offset), int64(req.Limit))
	if err != nil {
		return nil, err
	}
	//获取路线图信息
	roadmapIdList := []string{}
	for _, accessItem := range accessItemList {
		roadmapIdList = append(roadmapIdList, accessItem.RoadmapId)
	}
	roadmapItemList, err := roadmap_dao.RoadmapInfoDao.ListById(ctx, roadmapIdList)
	if err != nil {
		return nil, err
	}
	roadmapItemMap := map[string]*roadmap_dao.RoadmapInfoDbItem{}
	for _, roadmapItem := range roadmapItemList {
		roadmapItemMap[roadmapItem.RoadmapId] = roadmapItem
	}
	//生成结果
	recordList := []*roadmap_user_api.AccessRecord{}
	for _, accessItem := range accessItemList {
		record := accessItem.ToAccessRecord()
		roadmapItem, ok := roadmapItemMap[accessItem.RoadmapId]
		if ok {
			record.RoadmapTitle = roadmapItem.BasicInfo.Title
			record.RoadmapDesc = roadmapItem.BasicInfo.Desc
			record.CanUpdateRoadmap = (!roadmapItem.PubState && roadmapItem.OwnerUserId == sessionItem.UserId)
		}
		recordList = append(recordList, record)
	}

	return &roadmap_user_api.ListAccessResponse{
		Code:       roadmap_user_api.ListAccessResponse_CODE_OK,
		TotalCount: count,
		RecordList: recordList,
	}, nil
}

func (apiImpl *RoadmapUserApiImpl) RemoveAccess(ctx context.Context, req *roadmap_user_api.RemoveAccessRequest) (*roadmap_user_api.RemoveAccessResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_user_api.RemoveAccessResponse{
			Code:   roadmap_user_api.RemoveAccessResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	exist, err := roadmap_dao.AccessRecordDao.Exist(ctx, sessionItem.UserId, req.RoadmapId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_user_api.RemoveAccessResponse{
			Code: roadmap_user_api.RemoveAccessResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = roadmap_dao.AccessRecordDao.Remove(sessCtx, sessionItem.UserId, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		return &roadmap_user_api.RemoveAccessResponse{
			Code: roadmap_user_api.RemoveAccessResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_user_api.RemoveAccessResponse), nil
}
